package vashion.azeroth.core.manager.forest;

import java.util.Date;
import java.util.List;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import vashion.azeroth.contant.AzerothConstants;
import vashion.azeroth.contant.CommonErrorEnum;
import vashion.azeroth.contant.ForestErrorEnum;
import vashion.azeroth.core.common.NeedOperateFlow;
import vashion.azeroth.core.common.NeedPermission;
import vashion.azeroth.core.dao.BaseDao;
import vashion.azeroth.core.item.dao.PropertyValueDao;
import vashion.azeroth.core.item.pojo.PropertyMetaDO;
import vashion.azeroth.core.item.pojo.PropertyValueDO;
import vashion.azeroth.core.manager.impl.BaseManagerImpl;
import vashion.azeroth.core.pojo.common.OperateFlowEnum;
import vashion.azeroth.core.result.ApiResult;

/**
 * Created by tingting on 15/9/1. 基础属性管理
 */
@Service
public class BasePropertyValueManager extends BaseManagerImpl<PropertyValueDO> {

	private final static Logger log = LoggerFactory.getLogger(BasePropertyValueManager.class);

	@Autowired
	private PropertyValueDao propertyValueDao;

	@Autowired
	private BasePropertyManager basePropertyManager;

	@Override
	public BaseDao<PropertyValueDO> getDao() {
		return propertyValueDao;
	}

	@NeedPermission
	@NeedOperateFlow(operateIdArgLocation = 1, operateFlowEnum = OperateFlowEnum.FOREST)
	public ApiResult<Long> publishPropertyValue(PropertyValueDO propertyValueDO, long operateId) {
		if (null == propertyValueDO || propertyValueDO.getPropertyMetaId() <= 0
				|| StringUtils.isBlank(propertyValueDO.getValue())) {
			return ApiResult.newErrorResult(ForestErrorEnum.PROPERTY_ARG_ERROR.getErrorCode(),
					ForestErrorEnum.PROPERTY_ARG_ERROR.getErrorMessage());
		}
		// 检查property meta是否存在
		ApiResult<PropertyMetaDO> proertyMetaResult = basePropertyManager
				.getDetail(propertyValueDO.getPropertyMetaId());
		if (null == proertyMetaResult || null == proertyMetaResult.getData()) {
			return ApiResult.newErrorResult(ForestErrorEnum.FOREST_PROPERTY_IS_NULL.getErrorCode(),
					ForestErrorEnum.FOREST_PROPERTY_IS_NULL.getErrorMessage());
		}
		propertyValueDO.setPropertyMetaTitle(proertyMetaResult.getData().getTitle());
		fullProperty(propertyValueDO);
		PropertyValueDO dbValue = this.findByValue(propertyValueDO);
		if (null != dbValue) {
			return ApiResult.newErrorResult(ForestErrorEnum.ALREADY_EXITS.getErrorCode(),
					ForestErrorEnum.ALREADY_EXITS.getErrorMessage());
		}
		try {
			this.save(propertyValueDO);
		} catch (Exception e) {
			log.error("BasePropertyManager.publishProperty error, PropertyValueDO=" + propertyValueDO, e);
			return ApiResult.newErrorResult(ForestErrorEnum.PROPERTY_SYSTEM_ERROR.getErrorCode(),
					ForestErrorEnum.PROPERTY_SYSTEM_ERROR.getErrorMessage());
		}
		return ApiResult.newSuccessResult(propertyValueDO.getId());
	}

	public PropertyValueDO findByValue(PropertyValueDO value) {
		return propertyValueDao.findByValue(value);
	}

	private void fullProperty(PropertyValueDO PropertyValueDO) {
		PropertyValueDO.setGmtCreate(new Date());
		PropertyValueDO.setGmtModified(new Date());
	}

	/**
	 * 根据metaId获取valueList
	 *
	 * @param propertyIdList
	 * @param page
	 * @param pageSize
	 * @return
	 */
	public ApiResult<List<PropertyValueDO>> getFromMetaIdList(List<Long> propertyIdList, int page, int pageSize) {
		try {
			int start = (page - 1) * pageSize;
			List<PropertyValueDO> PropertyValueDOList = propertyValueDao.getFromMetaIdList(propertyIdList, start,
					pageSize);
			return ApiResult.newSuccessResult(PropertyValueDOList);
		} catch (Exception e) {
			log.error("BasePropertyManager.getPropertyList error propertyIdList=" + propertyIdList, e);
			return ApiResult.newErrorResult(ForestErrorEnum.PROPERTY_QUERY_ERROR.getErrorCode(),
					ForestErrorEnum.PROPERTY_QUERY_ERROR.getErrorMessage());
		}

	}

	/**
	 * 根据metaId获取valueList
	 *
	 * @param propertyIdList
	 * @param pageNum
	 * @param pageSize
	 * @return
	 */
	public ApiResult<List<PropertyValueDO>> getFromMetaId(Long propertyMetaId, int pageNum, int pageSize) {
		try {
			PropertyValueDO propertyValueParam = new PropertyValueDO();
			propertyValueParam.setPropertyMetaId(propertyMetaId);
			propertyValueParam.setStatus(AzerothConstants.ItemForestProperty.NORMAL);
			pageNum = pageNum < 1 ? 1 : pageNum;
			propertyValueParam.setFirstRow(pageSize * (pageNum - 1));
			propertyValueParam.setPageSize(1000);
			List<PropertyValueDO> PropertyValueDOList = propertyValueDao.find(propertyValueParam);
			return ApiResult.newSuccessResult(PropertyValueDOList);
		} catch (Exception e) {
			log.error("BasePropertyManager.getPropertyList error propertyIdList=" + propertyMetaId, e);
			return ApiResult.newErrorResult(ForestErrorEnum.PROPERTY_QUERY_ERROR.getErrorCode(),
					ForestErrorEnum.PROPERTY_QUERY_ERROR.getErrorMessage());
		}

	}

	public ApiResult<Integer> countPropertyValueList(List<Long> propertyIdList) {
		try {
			return ApiResult.newSuccessResult(propertyValueDao.countValueList(propertyIdList));
		} catch (Exception e) {
			log.error("BasePropertyManager.countPropertyValueList error propertyIdList=" + propertyIdList, e);
			return ApiResult.newErrorResult(ForestErrorEnum.PROPERTY_QUERY_ERROR.getErrorCode(),
					ForestErrorEnum.PROPERTY_QUERY_ERROR.getErrorMessage());
		}
	}

	/**
	 * 根据valueId获取列表
	 *
	 * @param idList
	 * @return
	 */
	public ApiResult<List<PropertyValueDO>> getValueList(List<Long> idList) {
		if (CollectionUtils.isEmpty(idList)) {
			return ApiResult.newErrorResult(CommonErrorEnum.ARG_ERROR.getErrorCode(),
					CommonErrorEnum.ARG_ERROR.getErrorMessage());
		}
		try {
			List<PropertyValueDO> PropertyValueDOList = propertyValueDao.getValueList(idList);
			return ApiResult.newSuccessResult(PropertyValueDOList);
		} catch (Exception e) {
			log.error("BasePropertyManager.getPropertyList error getValueList=" + idList, e);
			return ApiResult.newErrorResult(ForestErrorEnum.PROPERTY_QUERY_ERROR.getErrorCode(),
					ForestErrorEnum.PROPERTY_QUERY_ERROR.getErrorMessage());
		}
	}

	@NeedOperateFlow(operateIdArgLocation = 2, operateFlowEnum = OperateFlowEnum.FOREST)
	public int remove(PropertyValueDO propertyValueDO, Long operatorId) {
		return this.remove(propertyValueDO);
	}

	/**
	 * 冻结一个property的value
	 *
	 * @param propertyValueId
	 * @return
	 */
	@NeedOperateFlow(operateIdArgLocation = 1, operateFlowEnum = OperateFlowEnum.FOREST)
	public ApiResult<Boolean> freezePropertyValue(long propertyValueId, Long operatorId) {
		PropertyValueDO propertyValue = new PropertyValueDO();
		try {
			propertyValue.setId(propertyValueId);
			propertyValue.setStatus(AzerothConstants.ItemForestProperty.DELETE);
			boolean result = propertyValueDao.freezeOrResume(propertyValue);
			if (!result) {
				return ApiResult.newErrorResult(ForestErrorEnum.FOREST_PROPERTY_SYSTEM_ERROR.getErrorCode(),
						ForestErrorEnum.FOREST_PROPERTY_SYSTEM_ERROR.getErrorMessage());
			}
		} catch (Exception e) {
			log.error("BasePropertyManager.freezePropertyValue error propertyValueId=" + propertyValueId, e);
			return ApiResult.newErrorResult(ForestErrorEnum.FOREST_PROPERTY_SYSTEM_ERROR.getErrorCode(),
					ForestErrorEnum.FOREST_PROPERTY_SYSTEM_ERROR.getErrorMessage());
		}
		return ApiResult.newSuccessResult(true);
	}

	/**
	 * 恢复一个property的value
	 *
	 * @param propertyValueId
	 * @return
	 */
	@NeedOperateFlow(operateIdArgLocation = 1, operateFlowEnum = OperateFlowEnum.FOREST)
	public ApiResult<Boolean> resumePropertyValue(long propertyValueId, Long operatorId) {
		PropertyValueDO propertyValue = new PropertyValueDO();
		try {
			propertyValue.setId(propertyValueId);
			propertyValue.setStatus(AzerothConstants.ItemForestProperty.NORMAL);
			boolean result = propertyValueDao.freezeOrResume(propertyValue);
			if (!result) {
				return ApiResult.newErrorResult(ForestErrorEnum.FOREST_PROPERTY_SYSTEM_ERROR.getErrorCode(),
						ForestErrorEnum.FOREST_PROPERTY_SYSTEM_ERROR.getErrorMessage());
			}
		} catch (Exception e) {
			log.error("BasePropertyManager.freezePropertyValue error propertyValueId=" + propertyValueId, e);
			return ApiResult.newErrorResult(ForestErrorEnum.FOREST_PROPERTY_SYSTEM_ERROR.getErrorCode(),
					ForestErrorEnum.FOREST_PROPERTY_SYSTEM_ERROR.getErrorMessage());
		}
		return ApiResult.newSuccessResult(true);
	}
}
